﻿using System;
using System.Collections;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Wicresoft.XslDebugger
{
    public partial class InputUrlForm : Form
    {
        private enum FormState
        {
            Initial,
            GetRequest,
            GetRequestUrlWithParam,
            PostRequest
        }

        #region Fields

        private FormState m_FormState;
        private DataGridViewCellStyle m_DisabledDGCellStyle;
        private DataGridViewCellStyle m_NormalDGCellStyle;

        private String m_HtmlString;

        #endregion

        #region Consturctor

        public InputUrlForm()
        {
            InitializeComponent();

            m_HtmlString = String.Empty;

            m_NormalDGCellStyle = dgParamsGrid.RowsDefaultCellStyle;

            m_DisabledDGCellStyle = new DataGridViewCellStyle();
            m_DisabledDGCellStyle.BackColor = Color.LightGray;
            m_DisabledDGCellStyle.SelectionBackColor = Color.LightGray;
            m_DisabledDGCellStyle.ForeColor = Color.DarkGray;
            m_DisabledDGCellStyle.SelectionForeColor = Color.DarkGray;

            

            ArrayList encodingItems = new ArrayList();
            foreach (EncodingInfo ei in Encoding.GetEncodings())
            {
                encodingItems.Add(new EncodingItem(string.Format("{0}({1})",ei.DisplayName,ei.Name),ei.GetEncoding()));
            }
            encodingItems.Insert(0, new EncodingItem(string.Format("---------------------------------------------------------"), Encoding.Default));
            encodingItems.Insert(0, new EncodingItem(string.Format("Unicode"), Encoding.Unicode));
            encodingItems.Insert(0, new EncodingItem(string.Format("UTF-8"),  Encoding.UTF8));
            encodingItems.Insert(0, new EncodingItem(string.Format("GB2312"), Encoding.GetEncoding("GB2312")));
            encodingItems.Insert(0,new EncodingItem(string.Format("ANSI(Default)"),Encoding.Default));
            //encodingItems.Add(new EncodingItem("GB2312", Encoding.GetEncoding("GB2312")));
            //encodingItems.Add(new EncodingItem("UTF-8", Encoding.UTF8));
            //encodingItems.Add(new EncodingItem("Unicode", Encoding.Unicode));
            cboEncoding.DataSource = encodingItems ;
            cboEncoding.DisplayMember = "Name";
            cboEncoding.ValueMember = "Encoding";
            cboEncoding.SelectedIndex = 0;

            ContextToolTip.SetToolTip(ckbWithProxy, "Post the http request using IE proxy.");
            ContextToolTip.SetToolTip(ckbAutoCheckRequestEncoding, "After get the response stream, the charset of the\nstream will be detected, otherwise the encoding below will be used.");
            ContextToolTip.SetToolTip(ckbAutoConvent, "After get the string, Html tidy will be used to\n convent the html into xhtml.");
            

        }

        #endregion

        #region PrivateMethods

        private void ResetControlsState()
        {
            txtUrl.Text = "http://";
            dgParamsGrid.Rows.Clear();
            rdoGetRequest.Checked = true;
            rdoPostRequest.Checked = false;
            ckbWithProxy.Checked = false;
            cboEncoding.SelectedIndex = 0;

            SetControlsEnabled(FormState.GetRequest);
        }

        private void SetControlsEnabled(FormState newState)
        {
            if (m_FormState != newState)
            {
                m_FormState = newState;

                this.SuspendLayout();

                rdoGetRequest.Enabled = true;
                rdoPostRequest.Enabled = true;
                btnLoadParams.Enabled = true;
                dgParamsGrid.Enabled = true;
                dgParamsGrid.RowsDefaultCellStyle = m_NormalDGCellStyle;
                btnOk.Enabled = true;
                switch (m_FormState)
                {
                    case FormState.Initial:
                        btnLoadParams.Enabled = false;
                        dgParamsGrid.Enabled = false;
                        btnOk.Enabled = false;
                        break;
                    case FormState.GetRequest:
                        btnLoadParams.Enabled = false;
                        break;
                    case FormState.PostRequest:
                        break;
                    case FormState.GetRequestUrlWithParam:
                        rdoGetRequest.Enabled = false;
                        rdoPostRequest.Enabled = false;
                        btnLoadParams.Enabled = false;
                        dgParamsGrid.Enabled = false;
                        dgParamsGrid.RowsDefaultCellStyle = m_DisabledDGCellStyle;
                        break;
                    default:
                        throw new InvalidOperationException("Unknow form state");
                }

                this.ResumeLayout();
            }
        }

        private NameValueCollection GetParamCol()
        {
            NameValueCollection paramCol = new NameValueCollection();

            foreach (DataGridViewRow eachRow in dgParamsGrid.Rows)
            {
                if (!eachRow.IsNewRow)
                    paramCol.Add(eachRow.Cells[0].Value.ToString(), eachRow.Cells[1].Value.ToString());
            }

            return paramCol;
        }

        private void SetParamCol(NameValueCollection paramCol)
        {
            dgParamsGrid.Rows.Clear();
            foreach (String eachKey in paramCol.Keys)
                dgParamsGrid.Rows.Add(eachKey, paramCol[eachKey]);
        }

        private void InputUrlForm_Shown(object sender, EventArgs e)
        {
            ResetControlsState();
        }

        private void txtUrl_TextChanged(object sender, EventArgs e)
        {
            FormState newState = FormState.Initial;

            if (txtUrl.TextLength > 0)
            {
                if (txtUrl.Text.IndexOf('?') >= 0)
                {
                    rdoGetRequest.Checked = true;
                    newState = FormState.GetRequestUrlWithParam;
                }
                else
                {
                    if (rdoGetRequest.Checked)
                        newState = FormState.GetRequest;
                    if (rdoPostRequest.Checked)
                        newState = FormState.PostRequest;
                }
            }
            else
            {
                newState = FormState.Initial;
            }
            SetControlsEnabled(newState);
        }

        private void RequestMethodOption_Click(object sender, EventArgs e)
        {
            FormState newState = FormState.Initial;

            if (Object.ReferenceEquals(sender, rdoGetRequest))
                newState = FormState.GetRequest;
            else if (Object.ReferenceEquals(sender, rdoPostRequest))
                newState = FormState.PostRequest;
            SetControlsEnabled(newState);
        }

        private void btnLoadParams_Click(object sender, EventArgs e)
        {
            String htmlStr = String.Empty;
            String errInfo = String.Empty;
            Encoding curEncoding = null;

            curEncoding = (Encoding)cboEncoding.SelectedValue;
            if (HttpWebUtil.GetPageHtmlString(txtUrl.Text, curEncoding, ckbWithProxy.Checked,
                                              out htmlStr, out errInfo,
                                              ckbAutoConvent.Checked,ckbAutoCheckRequestEncoding.Checked))
            {
                SetParamCol(HttpWebUtil.GetPostParams(htmlStr));
            }
            else
            {
                MessageBox.Show(String.Format(Resources.InputUrlForm_LoadPostParams, errInfo),
                                Resources.MsgBox_Failed, MessageBoxButtons.OK,
                                MessageBoxIcon.Error);
            }
        }

        private void btnOk_Click(object sender, EventArgs e)
        {
            Boolean state = true;
            String urlStr = String.Empty;
            String htmlStr = String.Empty;
            String errInfo = String.Empty;
            Encoding curEncoding = null;

            curEncoding = (Encoding)cboEncoding.SelectedValue;
            urlStr = txtUrl.Text;

            if (!String.IsNullOrEmpty(urlStr))
            {
                this.Cursor = Cursors.WaitCursor;
                switch (m_FormState)
                {
                    case FormState.GetRequest :
                        state = HttpWebUtil.GetPageHtmlStringGet(urlStr, GetParamCol(), curEncoding,
                                                                 ckbWithProxy.Checked, out htmlStr, out errInfo,
                                                                 ckbAutoConvent.Checked,ckbAutoCheckRequestEncoding.Checked);
                        break;
                    case FormState.PostRequest :
                        state = HttpWebUtil.GetPageHtmlStringPost(urlStr, GetParamCol(), curEncoding,
                                                                  ckbWithProxy.Checked, out htmlStr, out errInfo,
                                                                  ckbAutoConvent.Checked, ckbAutoCheckRequestEncoding.Checked);
                        break;
                    case FormState.GetRequestUrlWithParam :
                        state = HttpWebUtil.GetPageHtmlString(urlStr, curEncoding, ckbWithProxy.Checked,
                                                              out htmlStr, out errInfo,
                                                              ckbAutoConvent.Checked, ckbAutoCheckRequestEncoding.Checked);
                        break;
                    default:
                        throw new InvalidOperationException("Invalid form state");
                }
            }
            else
            {
                state = false;
                errInfo = Resources.InputUrlForm_EmptyUrl;
            }

            if (state)
            {
                m_HtmlString = htmlStr;
                this.DialogResult = DialogResult.OK;
                this.Close();
            }
            else
            {
                MessageBox.Show(String.Format(Resources.InputUrlForm_FailedDownloadHtml, errInfo),
                                Resources.MsgBox_Failed, MessageBoxButtons.OK,
                                MessageBoxIcon.Error);
            }
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            m_HtmlString = String.Empty;
            this.DialogResult = DialogResult.Cancel;
            this.Close();
        }

        #endregion

        #region Properties

        public String HtmlString
        {
            get { return m_HtmlString; }
        }

        #endregion

        private void cboEncoding_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (cboEncoding.SelectedIndex == 4)
            {
                cboEncoding.SelectedIndex = 0;
            }
        }

    }

    public class EncodingItem
    {
        private String m_Name;
        private Encoding m_Encoding;

        public EncodingItem(String name, Encoding encoding)
        {
            m_Name = name;
            m_Encoding = encoding;
        }

        public String Name
        {
            get { return m_Name; }
        }

        public Encoding Encoding
        {
            get { return m_Encoding; }
        }
    }

}
